package modelo.red;

import java.util.List;

import org.hibernate.Query;
import org.hibernate.Session;

/**
 * 
 * @author edgar
 * Mantiene la informacion de cuatro puntos que rodean a un punto
 */
public class Pixel {
	private Malla malla;
	private int esteMin;
	private int esteMax;
	private int norteMin;
	private int norteMax;
	private int indEsteMin;
	private int indEsteMax;
	private int indNorteMin;
	private int indNorteMax;
	private double norte;
	private double este;
	private double val1;
	private double val2;
	private double val3;
	private double val4;
	private double valorPunto;
	private AtributoMalla atributo;
	private String error = "";
	public Malla getMalla() {
		return malla;
	}
	public void setMalla(Malla malla) {
		this.malla = malla;
	}
	public int getEsteMin() {
		return esteMin;
	}
	public void setEsteMin(int esteMin) {
		this.esteMin = esteMin;
	}
	public int getEsteMax() {
		return esteMax;
	}
	public void setEsteMax(int esteMax) {
		this.esteMax = esteMax;
	}
	public int getNorteMin() {
		return norteMin;
	}
	public void setNorteMin(int norteMin) {
		this.norteMin = norteMin;
	}
	public int getNorteMax() {
		return norteMax;
	}
	public void setNorteMax(int norteMax) {
		this.norteMax = norteMax;
	}
	public double getNorte() {
		return norte;
	}
	public void setNorte(double norte) {
		this.norte = norte;
	}
	public double getEste() {
		return este;
	}
	public void setEste(double este) {
		this.este = este;
	}
	
	public int getIndEsteMin() {
		return indEsteMin;
	}
	public void setIndEsteMin(int indEsteMin) {
		this.indEsteMin = indEsteMin;
	}
	public int getIndEsteMax() {
		return indEsteMax;
	}
	public void setIndEsteMax(int indEsteMax) {
		this.indEsteMax = indEsteMax;
	}
	public int getIndNorteMin() {
		return indNorteMin;
	}
	public void setIndNorteMin(int indNorteMin) {
		this.indNorteMin = indNorteMin;
	}
	public int getIndNorteMax() {
		return indNorteMax;
	}
	public void setIndNorteMax(int indNorteMax) {
		this.indNorteMax = indNorteMax;
	}
	public AtributoMalla getAtributo() {
		return atributo;
	}
	public void setAtributo(AtributoMalla atributo) {
		this.atributo = atributo;
	}

	public String getError() {
		return error;
	}
	public void setError(String error) {
		this.error = error;
	}
	
	public double getVal1() {
		return val1;
	}
	public void setVal1(double val1) {
		this.val1 = val1;
	}
	public double getVal2() {
		return val2;
	}
	public void setVal2(double val2) {
		this.val2 = val2;
	}
	public double getVal3() {
		return val3;
	}
	public void setVal3(double val3) {
		this.val3 = val3;
	}
	public double getVal4() {
		return val4;
	}
	public void setVal4(double val4) {
		this.val4 = val4;
	}
	public double getValorPunto() {
		return valorPunto;
	}
	public void setValorPunto(double valorPunto) {
		this.valorPunto = valorPunto;
	}
	public boolean calcularPuntos(Session sess){
		Query q;
		
		double valEsteMin, valEsteMax, valNorteMin, valNorteMax, dxy;
		
		boolean existe = true;
				
		
		q = sess.createQuery("From ValorAtributo as v where v.malla = :malla and v.norte.id = :norte and v.este.id = :este and v.atributo = :atributo");
		q.setParameter("malla", malla);
		q.setParameter("norte", norteMin);
		q.setParameter("este", esteMin);
		q.setParameter("atributo", atributo);
		List list = q.list();
		
		if(list.size()== 1){
			val1 = ((ValorAtributo) list.get(0)).getValor();
			
		}
		else {
			existe = false;
			error += " No EsteMin NorteMin ";
			
		}
		
		q = sess.createQuery("From ValorAtributo as v where (v.malla = :malla) and (v.norte.id = :norte) and (v.este.id = :este)");
		q.setParameter("malla", malla);
		q.setParameter("norte", norteMax);
		q.setParameter("este", esteMin);
		list = q.list();
		if(list.size()== 1){
			val2 = ((ValorAtributo) list.get(0)).getValor();
		}
		else {
			existe = false;
			error += " No EsteMin NorteMax ";
	

		}

		q = sess.createQuery("From ValorAtributo as v where (v.malla = :malla) and (v.norte.id = :norte) and (v.este.id = :este)");
		q.setParameter("malla", malla);
		q.setParameter("norte", norteMin);
		q.setParameter("este", esteMax);
		list = q.list();
		if(list.size()== 1){
			val3 = ((ValorAtributo) list.get(0)).getValor();
		}
		else {
			existe = false;
			error += " No EsteMax NorteMin ";
			

		}
		
		q = sess.createQuery("From ValorAtributo as v where (v.malla = :malla) and (v.norte.id = :norte) and (v.este.id = :este)");
		q.setParameter("malla", malla);
		q.setParameter("norte", norteMax);
		q.setParameter("este", esteMax);
		list = q.list();
		if(list.size()== 1){
			val4 = ((ValorAtributo) list.get(0)).getValor();
		}
		else {
			existe = false;
			error += " No EsteMax NorteMax ";


		}
		if(existe){
			valEsteMin = malla.getEjeEsteOeste().get(indEsteMin).getValor();
			valEsteMax = malla.getEjeEsteOeste().get(indEsteMax).getValor();
			valNorteMin = malla.getEjeNorteSur().get(indNorteMin).getValor();
			valNorteMax = malla.getEjeNorteSur().get(indNorteMax).getValor();
			if(malla.getTipo()==0) {

				dxy = (valEsteMax - valEsteMin)*(valNorteMax - valNorteMin);
				double desNorteMin = norte - valNorteMin;
				double desNorteMax = valNorteMax - norte;
				double desEsteMin = este - valEsteMin;
				double desEsteMax = valEsteMax - este;
				double resultado = (desNorteMax*(val1*desEsteMax+val3*desEsteMin)+ desNorteMin*(val2*desEsteMax+val4*desEsteMin))/dxy;
				
	//			System.out.println("Latitud " + norte + " longitud " + este + " resultado" + resultado);
	//			System.out.println("valores val1 "+ valNorteMin + ":" + norteMin +"," + valEsteMin + ":" + esteMin + "--" + val1);
	//			System.out.println("valores val2 "+ valNorteMax + ":" + norteMax +"," + valEsteMin + ":" + esteMin + "--" + val2);
	//			System.out.println("valores val3 "+ valNorteMin + ":" + norteMin +"," + valEsteMax + ":" + esteMax + "--" + val3);
	//			System.out.println("valores val1 "+ valNorteMax + ":" + norteMax +"," + valEsteMax + ":" + esteMax + "--" + val4);
				valorPunto = resultado;
			}
			else{
				double d1, d2, d3, d4, dmin;
				d1 = Math.sqrt((valEsteMin -este)*(valEsteMin -este) + (valNorteMin -norte)*(valNorteMin -norte));
				d2 = Math.sqrt((valEsteMin -este)*(valEsteMin -este) + (valNorteMax -norte)*(valNorteMax -norte));
				d3 = Math.sqrt((valEsteMax -este)*(valEsteMax -este) + (valNorteMin -norte)*(valNorteMin -norte));
				d4 = Math.sqrt((valEsteMax -este)*(valEsteMax -este) + (valNorteMax -norte)*(valNorteMax -norte));
				
				valorPunto = d1;
				if(valorPunto < d2) valorPunto = d2;
				if(valorPunto < d3) valorPunto = d3;
				if(valorPunto < d4) valorPunto = d4;
				
			}
		}
		else {
			valorPunto = 0;
			return false;
		}
		return existe;
	}
}
		

